#include<iostream>
#include<algorithm>
#include<cmath>
#include"Graph.h"

int main()
{
	//以下测试代码实现了用户选择存储方式、添加两个顶点、添加两条边、
	//更改一个顶点、更改一条边、删除一个顶点、删除一条边等过程。
	std::cout << "It's the test for the graph." << std::endl;
	std::cout << "Now input amounts of vertexes and edges you want to construct." << std::endl;

	int vertex = 0;
	int edge = 0;
	std::cin >> vertex >> edge;

	char point[vertex+2][11];    //存储输入的顶点名称。
	int endpoint[edge][2];    //存储输入的边的顶点下标。
	int weight[edge];    //存储输入的边的权重。
	int t = 0;	//代表用户选择用邻接矩阵方式、邻接表方式或者按实际情况决定。
	int newedgepoint11 = 0, newedgepoint12 = 0;    //添加的第一条边的两个端点下标。
	int newedgepoint21 = 0, newedgepoint22 = 0;    //添加的第二条边的两个端点下标。
	int newweight1 = 0, newweight2 = 0;    //添加的两条边的权重值。
	int curredgepoint1 = 0, curredgepoint2 = 0;    //需要更改的边的两个端点下标。
	int currweight = 0;    //需要更改的边的新权重数值。
	int oldedgepoint1 = 0, oldedgepoint2 = 0;    //删除的边的两个顶点下标。
	int oldpoint = 0;    //删除的顶点的下标。

	std::cout << "Now input names of vertexes.(No more than 10 characters)" << std::endl;
	for(int i = 0; i < vertex; i++)
	{
		std::cin >> point[i];
	}
	std::cout << "Now input indexs of edges and weights of edges.(If the graph is unweighted,take all weights as 1.)" << std::endl;
	for(int i = 0; i < edge; i++)
	{
		std::cin >> endpoint[i][0] >> endpoint[i][1] >> weight[i];
	}
	//用户选择存储方式。
	std::cout << "Now choose the way of storing the graph.(adjacency matrix:1/adjacent list:2/unspecified:3)" << std::endl;
    std::cin >> t;
	//用户选择输入为1或者输入为3且边数较多，选择邻接矩阵存储方式。
	if(t == 1 || t == 3 && edge >= vertex*log(vertex))
	{
		std::cout << "We use the adjacency matrix." << std::endl;
		Graph1<int, char*> graph1(vertex);
		for(int j = 0; j < vertex; j++)
		{
			graph1.setPoint(j,point[j]);
		}
		for(int j = 0; j < edge; j++)
		{
			graph1.addEdge(point[endpoint[j][0]],point[endpoint[j][1]],weight[j]);
		}
		graph1.listVertexes();
		graph1.listEdges();
	    std::cout << "The amount of edges is " << graph1.getEdgeCount() << std::endl;
		std::cout << "The amount of vertexes is " << graph1.getPointCount() << std::endl;
		//添加两个顶点。
		std::cout << "Now input names of two points that need to be added." << std::endl;
		std::cin >> point[vertex] >> point[vertex+1];
		graph1.addPoint(point[vertex]);
		graph1.addPoint(point[vertex+1]);
		//添加两条边。
		std::cout << "Now we need to add two edges.Please input indexes of endpoints and weights." << std::endl;
		std::cin >> newedgepoint11 >> newedgepoint12 >> newweight1;
		std::cin >> newedgepoint21 >> newedgepoint22 >> newweight2;
		graph1.addEdge(point[newedgepoint11],point[newedgepoint12],newweight1);
		graph1.addEdge(point[newedgepoint21],point[newedgepoint22],newweight2);
		graph1.listVertexes();
		graph1.listEdges();
	    std::cout << "The amount of edges is " << graph1.getEdgeCount() << std::endl;
		std::cout << "The amount of vertexes is " << graph1.getPointCount() << std::endl;	
		//更改一条边。
		std::cout << "Now we need to change the weight of an edge.Please input indexes of endpoints and the weight." << std::endl;
		std::cin >> curredgepoint1 >> curredgepoint2 >> currweight;
		graph1.setEdge(point[curredgepoint1],point[curredgepoint2],currweight);
		graph1.listVertexes();
		graph1.listEdges();
		//删除一条边。
		std::cout << "Now we need to remove an edge.Please input indexes of endpoints." << std::endl;
		std::cin >> oldedgepoint1 >> oldedgepoint2;
		graph1.removeEdge(point[oldedgepoint1],point[oldedgepoint2]);
		//删除一个顶点。
		std::cout << "Now input the index of a point you want to remove." << std::endl;
		std::cin >> oldpoint;
		graph1.removePoint(point[oldpoint]);
		graph1.listVertexes();
		graph1.listEdges();
	    std::cout << "The amount of edges is " << graph1.getEdgeCount() << std::endl;
		std::cout << "The amount of vertexes is " << graph1.getPointCount() << std::endl;	
	}
	//用户选择输入为2或者输入为3且边数较少，选择邻接表存储方式。
	else if(t == 2 || t == 3 && edge < vertex*log(vertex))
	{
		std::cout << "We use the adjacent list." << std::endl;
		Graph2<int, char*> graph2(vertex);
		for(int j = 0; j < vertex; j++)
		{
			graph2.setVertexName(j,point[j]);
		}
		for(int j = 0; j < edge; j++)
		{
			graph2.addEdge(point[endpoint[j][0]],point[endpoint[j][1]],weight[j]);
		}
		graph2.listVertexes();
		graph2.listEdges();
	    std::cout << "The amount of edges is " << graph2.edgeCount() << std::endl;
		std::cout << "The amount of vertexes is " << graph2.vertexCount() << std::endl;
		//添加两个顶点。
		std::cout << "Now input names of two points that need to be added." << std::endl;
		std::cin >> point[vertex] >> point[vertex+1];
		graph2.addVertex(point[vertex]);
		graph2.addVertex(point[vertex+1]);
		//添加两条边。
		std::cout << "Now we need to add two edges.Please input indexes of endpoints and weights." << std::endl;
		std::cin >> newedgepoint11 >> newedgepoint12 >> newweight1;
		std::cin >> newedgepoint21 >> newedgepoint22 >> newweight2;
		graph2.addEdge(point[newedgepoint11],point[newedgepoint12],newweight1);
		graph2.addEdge(point[newedgepoint21],point[newedgepoint22],newweight2);
		graph2.listVertexes();
		graph2.listEdges();
	    std::cout << "The amount of edges is " << graph2.edgeCount() << std::endl;
		std::cout << "The amount of vertexes is " << graph2.vertexCount() << std::endl;	
		//更改一条边。
		std::cout << "Now we need to change the weight of an edge.Please input indexes of endpoints and the weight." << std::endl;
		std::cin >> curredgepoint1 >> curredgepoint2 >> currweight;
		graph2.setEdgeValue(point[curredgepoint1],point[curredgepoint2],currweight);
		graph2.listVertexes();
		graph2.listEdges();
		//删除一条边。
		std::cout << "Now we need to remove an edge.Please input indexes of endpoints." << std::endl;
		std::cin >> oldedgepoint1 >> oldedgepoint2;
		graph2.removeEdge(point[oldedgepoint1],point[oldedgepoint2]);
		//删除一个顶点。
		std::cout << "Now input the index of a point you want to remove." << std::endl;
		std::cin >> oldpoint;
		graph2.removeVertex(point[oldpoint]);
		graph2.listVertexes();
		graph2.listEdges();	
	    std::cout << "The amount of edges is " << graph2.edgeCount() << std::endl;
		std::cout << "The amount of vertexes is " << graph2.vertexCount() << std::endl; 
	}

    return 0;
}